package snuggle.jabber.utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.ChatManager;
import org.jivesoftware.smack.Roster;
import org.jivesoftware.smack.RosterEntry;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Presence;

import snuggle.jabber.bot.SnuggleBot;
import snuggle.jabber.listeners.MessageList;

public class MessageUtils {

	private List<String> admins;
	private Roster roster;
	private String host;
	private ChatManager chatManager;

	private static Logger logger = Logger.getLogger(MessageUtils.class);
	
	public MessageUtils(String host, Roster roster, ChatManager chatManager,
			List<String> admins) {
		this.roster = roster;
		this.admins = admins;
		this.host = host;
		this.chatManager = chatManager;
	}

	public void parseMessage(String sender, Message message)
			throws NotConnectedException {
		String body = message.getBody();

		sender = trimUser(sender);

		if (admins.contains(sender)) { // Admin message
			logger.info("Admin message from: " + sender + ": " + body);
			if (body.equals("exit")) { // Quit
				SnuggleBot.exit();
			} else if (body.startsWith("ping ")) { // Send a broadcast
				body = body.substring(5);
				String group = body.substring(0, body.indexOf(' '));
				String text = body.substring(body.indexOf(' ') + 1);

				logger.info("Ping for " + group + ": " + text);

				broadcast(roster, sender, group, text);
			}
		} else { // Non-admin message
			logger.info("Received message from " + sender + ": " + body);
		}
	}

	public void sendMessage(String user, String text)
			throws NotConnectedException {
		Chat chat = chatManager.createChat(user, new MessageList());
		Message message = new Message();
		message.setBody(text);

		chat.sendMessage(message);
		chat.close();
	}

	public void broadcast(Roster roster, String sender, String group,
			String text) throws NotConnectedException {

		Collection<RosterEntry> entries;
		if (group.equals("all"))
			entries = roster.getEntries();
		else
			entries = roster.getGroup(group).getEntries();

		ArrayList<String> users = new ArrayList<String>();
		Presence presence;
		String user;

		for (RosterEntry entry : entries) {
			user = entry.getUser();
			presence = roster.getPresence(user);
			if (Presence.Type.available == presence.getType())
				users.add(user);
		}

		logger.info("Online members (" + users.size() + "):");
		logger.info(users);

		StringBuilder sb = new StringBuilder();
		sb.append("\r\n==BROADCAST MESSAGE==\r\n");
		sb.append(text);
		sb.append("\r\n");
		sb.append("Sent by ");
		sb.append(sender);
		sb.append(" to ");
		sb.append(group);
		sb.append(".");

		for (String recipient : users) {
			sendMessage(recipient, sb.toString());
		}
	}

	private String trimUser(String user) {
		int last = user.lastIndexOf("@" + host);
		return user.substring(0, last + host.length() + 1);
	}

}
